package org.springblade.modules.platform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.modules.platform.dto.PhysicalDataTableDTO;
import org.springblade.modules.platform.dto.PhysicalDataTableListByPageDTO;
import org.springblade.modules.platform.entity.*;
import org.springblade.modules.platform.mapper.*;
import org.springblade.modules.platform.service.IEngineerValueTableService;

import org.springblade.modules.platform.utils.TimeUtils;
import org.springblade.modules.platform.vo.*;
import org.springblade.core.tool.utils.DateUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author SYG
 * @since 2022-12-08
 */
@Service
public class EngineerValueTableServiceImpl extends ServiceImpl<EngineerValueTableMapper, EngineerValueTable> implements IEngineerValueTableService {
	@Autowired
	AbsolutelyValueTableMapper absolutelyValueTableMapper;
	@Autowired
	EngineerValueRepairTableMapper engineerValueRepairTableMapper;
	@Autowired
	MeasuringChainPlatformTypeMapper measuringChainPlatformTypeMapper;

	@Autowired
	MeasuringChainPlatformInfoMapper mapper;

    @Override
    public EngineerValueTablePageVO getListByPage(PhysicalDataTableListByPageDTO physicalDataTableListByPageDTO) {
        EngineerValueTablePageVO engineerValueTablePageVO = new EngineerValueTablePageVO();
        QueryWrapper<EngineerValueTable> queryWrapper = new QueryWrapper<>();

        if(physicalDataTableListByPageDTO.getEndTime()!=null&&physicalDataTableListByPageDTO.getStartTime()!=null){
            queryWrapper.lambda().ge(EngineerValueTable::getGatherTime,physicalDataTableListByPageDTO.getStartTime()).le(EngineerValueTable::getGatherTime,physicalDataTableListByPageDTO.getEndTime());
        }
        if(physicalDataTableListByPageDTO.getGatherEvent()!=null){
            queryWrapper.lambda().eq(EngineerValueTable::getGatherEvent,physicalDataTableListByPageDTO.getGatherEvent());
        }
        if(physicalDataTableListByPageDTO.getMeasurChain()!=null){
            queryWrapper.lambda().like(EngineerValueTable::getMeasurChain,physicalDataTableListByPageDTO.getMeasurChain());
        }

        queryWrapper.lambda().orderByDesc(EngineerValueTable::getGatherTime);
        Page<EngineerValueTable> rawDataTablePage = baseMapper.selectPage(new Page<>(physicalDataTableListByPageDTO.getCurrent(), physicalDataTableListByPageDTO.getSize()), queryWrapper);
        engineerValueTablePageVO.setTotal(rawDataTablePage.getTotal());
        if(rawDataTablePage.getTotal()>0){

            List<EngineerValueTable> records = rawDataTablePage.getRecords();
            List<EngineerValueTableVO> collect = records.stream().map(x -> {
                EngineerValueTableVO engineerValueTableVO = new EngineerValueTableVO();
                BeanUtils.copyProperties(x, engineerValueTableVO);
                engineerValueTableVO.setGatherEvent(x.getGatherEvent()==2?"手动采集"+x.getAcquisitionFlag():"定时采集");
                return engineerValueTableVO;
            }).collect(Collectors.toList());
            engineerValueTablePageVO.setList(collect.stream().sorted(Comparator.comparing(EngineerValueTableVO::getId)).collect(Collectors.toList()));
        }
        return engineerValueTablePageVO;
    }

    @Override
    public DataDetailsVO.EngineerValueTableVO selectListByDeptId(Long deptId, Long gatherTime, Integer measurChainDirection) {
        EngineerValueTable engineerValueTable = baseMapper.selectOne(Wrappers.<EngineerValueTable>query().lambda()
                .eq(EngineerValueTable::getGatherTime, gatherTime)
                .eq(EngineerValueTable::getMeasurChainDirection, measurChainDirection)
                .eq(EngineerValueTable::getDeptId, deptId));
        if(engineerValueTable != null){
            DataDetailsVO.EngineerValueTableVO engineerValueTableVO = new DataDetailsVO.EngineerValueTableVO();
            BeanUtils.copyProperties(engineerValueTable, engineerValueTableVO);
            return engineerValueTableVO;
        }

        return null;
    }

    @Override
    public ProductionChartVO getChart(Long measurChainCode, Long gatherTime,Integer measurChainDirection) {
		LambdaQueryWrapper<EngineerValueTable> eq = Wrappers.<EngineerValueTable>query().lambda()
			.eq(EngineerValueTable::getGatherTime, gatherTime)
			.eq(EngineerValueTable::getMeasurChainCode, measurChainCode);
		if(measurChainDirection!=null){
			eq.eq(EngineerValueTable::getMeasurChainDirection, measurChainDirection);
		}
		List<EngineerValueTable> engineerValueTables = baseMapper.selectList(eq);
        if(CollectionUtils.isEmpty(engineerValueTables)){
           return null;
        }

		List<MeasuringChainPlatformType> measuringChainPlatformTypes = measuringChainPlatformTypeMapper.selectList(new QueryWrapper<MeasuringChainPlatformType>().lambda()
			.eq(MeasuringChainPlatformType::getMeasuringChainId, measurChainCode));
		MeasuringChainPlatformType measuringChainPlatformType1 = measuringChainPlatformTypes.stream().filter(x -> x.getMeasuringTypeCode() == 1).findFirst().get();
		MeasuringChainPlatformType measuringChainPlatformType2 = measuringChainPlatformTypes.stream().filter(x -> x.getMeasuringTypeCode() == 2).findFirst().get();

		List<MeasuringChainPlatformInfo> measuringChainPlatformInfos = mapper.selectList(new QueryWrapper<MeasuringChainPlatformInfo>().lambda()
				.eq(MeasuringChainPlatformInfo::getMeasuringTypeId, measuringChainPlatformType1.getId())
			.orderByAsc(MeasuringChainPlatformInfo::getSort));

		List<MeasuringChainPlatformInfo> measuringChainPlatformInfos2 = mapper.selectList(new QueryWrapper<MeasuringChainPlatformInfo>().lambda()
				.eq(MeasuringChainPlatformInfo::getMeasuringTypeId, measuringChainPlatformType2.getId())
			.orderByDesc(MeasuringChainPlatformInfo::getSort));

			List<EngineerValueTable> collect2 = new ArrayList<>();
		for (MeasuringChainPlatformInfo measuringChainPlatformInfo : measuringChainPlatformInfos) {
			EngineerValueTable engineerValueTable = engineerValueTables.stream().filter(x -> x.getMeasurChainDirection() == 1 && Objects.equals(x.getDeptId(), measuringChainPlatformInfo.getMeasuringPlatformId())).findFirst().orElse(null);
			if(engineerValueTable!=null){
				collect2.add(engineerValueTable);
			}
		}
	for (MeasuringChainPlatformInfo measuringChainPlatformInfo : measuringChainPlatformInfos2) {
			EngineerValueTable engineerValueTable = engineerValueTables.stream().filter(x -> x.getMeasurChainDirection() == 2 && Objects.equals(x.getDeptId(), measuringChainPlatformInfo.getMeasuringPlatformId())).findFirst().orElse(null);
			if(engineerValueTable!=null){
				collect2.add(engineerValueTable);
			}
		}
		ProductionChartVO productionChartVO = new ProductionChartVO();
        List<ProductionChartVO.DeptBenchInfoVO> deptBenchInfoVOS = new ArrayList<>();
		collect2.forEach(x->{
            ProductionChartVO.DeptBenchInfoVO deptBenchInfoVO = new ProductionChartVO.DeptBenchInfoVO();
            deptBenchInfoVO.setDeptId(x.getDeptId());
            deptBenchInfoVO.setDeptName(x.getDeptName());
            deptBenchInfoVO.setGatherTime(TimeUtils.timeStampConversionTime(x.getGatherTime(),DateUtil.PATTERN_DATETIME));
            deptBenchInfoVO.setXAxis(x.getX());
            deptBenchInfoVO.setZAxis(x.getZ());
            deptBenchInfoVO.setYAxis(x.getY());
            deptBenchInfoVOS.add(deptBenchInfoVO);

        });

        productionChartVO.setDeptBenchInfoVOS(deptBenchInfoVOS);
        return productionChartVO;
    }

    @Override
    public ProductionChartVO getProductionChart(Long deptId,Integer measurChainDirection, Long startTime, Long endTime) {
        QueryWrapper<EngineerValueTable> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(EngineerValueTable::getDeptId,deptId)
                .eq(EngineerValueTable::getMeasurChainDirection,measurChainDirection);
        if(startTime!=null&&endTime!=null){
            queryWrapper.lambda().between(EngineerValueTable::getGatherTime,startTime,endTime);
        }else {
            Date date = TimeUtils.currentMax(new Date());
            Date date1 =  TimeUtils.localDateTime2Date(TimeUtils.localDateTimeSubtractionDay(TimeUtils.date2LocalDateTime(new Date()),1000));
            queryWrapper.lambda().between(EngineerValueTable::getGatherTime,date1.getTime(),date.getTime());
        }
		 queryWrapper.lambda().orderByAsc(EngineerValueTable::getGatherTime).orderByDesc(EngineerValueTable::getId);
        List<EngineerValueTable> engineerValueTables = baseMapper.selectList(queryWrapper);
        if(CollectionUtils.isEmpty(engineerValueTables)){
            return null;
        }
        ProductionChartVO productionChartVO = new ProductionChartVO();
        List<ProductionChartVO.DeptBenchInfoVO> deptBenchInfoVOS = new ArrayList<>();
        engineerValueTables.forEach(x->{
            ProductionChartVO.DeptBenchInfoVO deptBenchInfoVO = new ProductionChartVO.DeptBenchInfoVO();
			deptBenchInfoVO.setTimeUtils(x.getGatherTime());
            deptBenchInfoVO.setDeptId(x.getDeptId());
            deptBenchInfoVO.setDeptName(x.getDeptName());
            deptBenchInfoVO.setGatherTime(TimeUtils.timeStampConversionTime(x.getGatherTime(), DateUtil.PATTERN_DATETIME));
            deptBenchInfoVO.setXAxis(x.getX());
			deptBenchInfoVO.setXCompany("mm");
			deptBenchInfoVO.setXName("X方向的绝对变形量");

            deptBenchInfoVO.setZAxis(x.getZ());
			deptBenchInfoVO.setZCompany("mm");
			deptBenchInfoVO.setZName("Z方向的绝对变形量");

            deptBenchInfoVO.setYAxis(x.getY());
			deptBenchInfoVO.setYCompany("mm");
			deptBenchInfoVO.setYName("Y方向的绝对变形量");


            deptBenchInfoVO.setAlpha(x.getAlpha());
			deptBenchInfoVO.setAlphaCompany("°");
			deptBenchInfoVO.setAlphaName("绕X方向的旋转角");


            deptBenchInfoVO.setGama(x.getGama());
			deptBenchInfoVO.setGamaCompany("°");
			deptBenchInfoVO.setGamaName("绕Z轴的旋转角");

            deptBenchInfoVO.setBeta(x.getBeta());
			deptBenchInfoVO.setBetaCompany("°");
			deptBenchInfoVO.setBetaName("绕Y轴的旋转角");


            deptBenchInfoVOS.add(deptBenchInfoVO);
        });
        productionChartVO.setDeptBenchInfoVOS(deptBenchInfoVOS);
        return productionChartVO;
    }

    @Override
    public EngineerValueTableVO getOneEngineerValue(Long deptId,Integer measurChainDirection) {
        List<EngineerValueTable> engineerValueTables = baseMapper.selectList(Wrappers.<EngineerValueTable>query().lambda()
                .eq(EngineerValueTable::getDeptId, deptId)
			.eq(EngineerValueTable::getMeasurChainDirection, measurChainDirection).orderByDesc(EngineerValueTable::getGatherTime).last("LIMIT 1"));
        if(CollectionUtils.isEmpty(engineerValueTables)){
            return null;
        }
        EngineerValueTableVO engineerValueTableVO = new EngineerValueTableVO();
        EngineerValueTable engineerValueTable = engineerValueTables.get(0);
        BeanUtils.copyProperties(engineerValueTable,engineerValueTableVO);
        return engineerValueTableVO;
    }

	@Override
	public void selectEngineerValue(PhysicalDataTableDTO physicalDataTableDTO) {
		List<EngineerValueTable> physicalValueTables = baseMapper.selectList(Wrappers.<EngineerValueTable>query().lambda()
			.eq(EngineerValueTable::getGatherTime, physicalDataTableDTO.getGatherTime())
			.eq(EngineerValueTable::getMeasurChainCode, physicalDataTableDTO.getMeasurChainCode()));
		if(!CollectionUtils.isEmpty(physicalValueTables)){
			absolutelyValueTableMapper.delete(Wrappers.<AbsolutelyValueTable>query().lambda());
			engineerValueRepairTableMapper.delete(Wrappers.<EngineerValueRepairTable>query().lambda());
			physicalValueTables.forEach(x-> engineerValueRepairTableMapper.insert(BeanUtil.copy(x, EngineerValueRepairTable.class)));
		}
	}
}
